package com.example.flutter_jl_bluetooth_plugin.ota

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothProfile
import android.content.Context
import com.example.flutter_jl_bluetooth_plugin.ble.BleManager
import com.example.flutter_jl_bluetooth_plugin.ble.interfaces.BleEventCallback
import com.jieli.jl_bt_ota.constant.StateCode
import com.jieli.jl_bt_ota.impl.BluetoothOTAManager
import com.jieli.jl_bt_ota.model.BluetoothOTAConfigure
import com.jieli.jl_bt_ota.model.base.BaseError
import com.jieli.jl_bt_ota.tool.DeviceReConnectManager
import com.jieli.jl_bt_ota.util.BluetoothUtil
import com.jieli.jl_bt_ota.util.CHexConver
import com.jieli.jl_bt_ota.util.JL_Log
import java.util.*

/**
 * 用于RCSP的第三方SDK接入OTA流程
 *
 * create Data:2019-08-21
 * create by:chensenhua
 */
class OTAManager(context: Context, operation: BluetoothOTAConfigure) : BluetoothOTAManager(context) {

    private val bleManager: BleManager = BleManager.getInstance()

    companion object {

        fun changeConnectStatus(status: Int): Int {
            var changeStatus = StateCode.CONNECTION_DISCONNECT
            when (status) {
                BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING -> changeStatus =
                        StateCode.CONNECTION_DISCONNECT
                BluetoothProfile.STATE_CONNECTED -> changeStatus = StateCode.CONNECTION_OK
                BluetoothProfile.STATE_CONNECTING -> changeStatus = StateCode.CONNECTION_CONNECTING
            }
            return changeStatus
        }
    }

    private val bleEventCallback = object : BleEventCallback() {
        override fun onBleConnection(device: BluetoothDevice?, status: Int) {
            super.onBleConnection(device, status)
            JL_Log.i(
                    TAG,
                    "onBleConnection >>> device : ${BluetoothUtil.printBtDeviceInfo(device)}, status ：$status, change status : ${changeConnectStatus(
                            status
                    )}"
            )
            onBtDeviceConnection(
                    device,
                    changeConnectStatus(
                            status
                    )
            )
        }

        override fun onBleDataNotification(
                device: BluetoothDevice?,
                serviceUuid: UUID?,
                characteristicsUuid: UUID?,
                data: ByteArray?
        ) {
            super.onBleDataNotification(device, serviceUuid, characteristicsUuid, data)
            JL_Log.i(
                    TAG,
                    "onBleDataNotification >>> ${BluetoothUtil.printBtDeviceInfo(device)}, data ：${CHexConver.byte2HexStr(
                            data
                    )} "
            )
            onReceiveDeviceData(device, data)
        }

        override fun onBleDataBlockChanged(device: BluetoothDevice?, block: Int, status: Int) {
            super.onBleDataBlockChanged(device, block, status)
            onMtuChanged(bleManager.connectedBtGatt, block, status)
        }
    }

    init {
        //配置OTA参数
        configure(operation)

        bleManager.registerBleEventCallback(bleEventCallback)
        if (bleManager.connectedBtDevice != null) {
            onBtDeviceConnection(bleManager.connectedBtDevice, StateCode.CONNECTION_OK)
            onMtuChanged(
                    bleManager.connectedBtGatt, bleManager.bleMtu + 3,
                    BluetoothGatt.GATT_SUCCESS
            )
        }
    }


    override fun getConnectedDevice(): BluetoothDevice? {
        return bleManager.connectedBtDevice
    }

    override fun getConnectedBluetoothGatt(): BluetoothGatt? {
        return bleManager.connectedBtGatt
    }

    override fun connectBluetoothDevice(bluetoothDevice: BluetoothDevice?) {
        bleManager.connectBleDevice(bluetoothDevice)
    }

    override fun disconnectBluetoothDevice(bluetoothDevice: BluetoothDevice?) {
        bleManager.disconnectBleDevice(bluetoothDevice)
    }

    override fun sendDataToDevice(bluetoothDevice: BluetoothDevice?, bytes: ByteArray?): Boolean {
//        val ret = bluetoothClient.jlBtManager.sendDataToDevice(bluetoothDevice, bytes)
//        JL_Log.d("zzc_bluetooth", "sendDataToDevice : ret = $ret")
        if (bluetoothDevice == null || bytes == null) return false
        bleManager.writeDataByBleAsync(
                bluetoothDevice,
                BleManager.BLE_UUID_SERVICE,
                BleManager.BLE_UUID_WRITE,
                bytes
        ) { device, serviceUUID, characteristicUUID, result, data ->
            JL_Log.i(
                    TAG,
                    "-writeDataByBleAsync- result = $result, device:${BluetoothUtil.printBtDeviceInfo(
                            device
                    )}, data:[${CHexConver.byte2HexStr(
                            data
                    )}]"
            )
        }
        return true
    }

    override fun errorEventCallback(baseError: BaseError) {

    }

    override fun release() {
        super.release()
        bleManager.unregisterBleEventCallback(bleEventCallback)
    }

    fun setReconnectAddr(addr: String?) {
        if (BluetoothAdapter.checkBluetoothAddress(addr)) {
            DeviceReConnectManager.getInstance(this).reconnectAddress = addr
        }
    }

}
